package org.facyt.vacas.services.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.facyt.vacas.dao.ClasificacionDAO;
import org.facyt.vacas.dao.ComponenteValorDAO;
import org.facyt.vacas.dao.GrupoDAO;
import org.facyt.vacas.dao.MateriaPrimaDAO;
import org.facyt.vacas.dao.UnidadDAO;
import org.facyt.vacas.entities.login.Grupo;
import org.facyt.vacas.entities.vacas.Clasificacion;
import org.facyt.vacas.entities.vacas.Componente;
import org.facyt.vacas.entities.vacas.ComponenteValor;
import org.facyt.vacas.entities.vacas.MateriaPrima;
import org.facyt.vacas.entities.vacas.Unidad;
import org.facyt.vacas.services.MateriasPrimasService;
import org.facyt.vacas.util.Constantes;
import org.facyt.vacas.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;


public class MateriasPrimasServiceImpl implements MateriasPrimasService {
	private static final Log logger = LogFactory.getLog(MateriasPrimasServiceImpl.class);
	private MateriaPrimaDAO materiaPrimaDao;
	private UnidadDAO unidadDAO;
	private ClasificacionDAO clasificacionDAO;
	private ComponenteValorDAO componenteValorDao;
	private GrupoDAO grupoDAO;
	private String mensaje = "";

	public MateriaPrimaDAO getMateriaPrimaDao() {
		return materiaPrimaDao;
	}

	public void setMateriaPrimaDao(MateriaPrimaDAO materiaPrimaDao) {
		this.materiaPrimaDao = materiaPrimaDao;
	}
	
	public ComponenteValorDAO getComponenteValorDao() {
		return componenteValorDao;
	}

	public void setComponenteValorDao(ComponenteValorDAO componenteValorDao) {
		this.componenteValorDao = componenteValorDao;
	}


	public MateriaPrima getMateriaPrimaById(Integer idMp) throws Exception {
		return materiaPrimaDao.getMateriaPrimaById(idMp);

	}

	
//	public List<Nodo> getTodasMateriasPrima(long idGrupoUsuario)
//			throws Exception {
//		List<Nodo> listaresultado = new ArrayList<Nodo>();
//		List<MateriaPrima> lista = materiaPrimaDao
//				.getAllMateriaPrima(idGrupoUsuario);
//
//		Collections.sort(lista,new OrdenarMateriaPrimaNombre());
//		
//		for (MateriaPrima mp : lista) {
//			Nodo nodo = new Nodo();
//			nodo.setCodigo(mp.getId());
//			nodo.setDescripcion(mp.getDescripcion());
//			listaresultado.add(nodo);
//		}
//
//		
//		return listaresultado;
//	}

	@Transactional
	
	public MateriaPrima nuevaMp(long idGrupoUsuario, String descripcion,
			long idUnidad, BigDecimal costo, long idClasificacion) throws Exception {

		Unidad unidad = this.unidadDAO.getUnidadById(Long.valueOf(idUnidad)
				.intValue());

		Clasificacion clasificacion = this.clasificacionDAO
				.getClasificacionById(Long.valueOf(idClasificacion).intValue());

		Grupo grupo = this.grupoDAO.getGrupoById(Long.valueOf(idGrupoUsuario)
				.intValue());

		MateriaPrima mp = materiaPrimaDao.nuevaMateriaPrima(grupo, descripcion,
				unidad, costo, clasificacion);

		mp = materiaPrimaDao.getMateriaPrimaById(mp.getId());
		return mp;
	}

	@Transactional
	
	public MateriaPrima updateMp(long idMP, long idUnidad, BigDecimal costo,
			long idClasificacion, String nombre) throws Exception {

		Unidad unidad = this.unidadDAO.getUnidadById(Long.valueOf(idUnidad)
				.intValue());

		Clasificacion clasificacion = this.clasificacionDAO
				.getClasificacionById(Long.valueOf(idClasificacion).intValue());


		MateriaPrima mp = materiaPrimaDao.updateMateriaPrima(idMP,unidad, costo, clasificacion, nombre);

		mp = materiaPrimaDao.getMateriaPrimaById(mp.getId());
		return mp;
	}
	
	@Transactional
	
	public MateriaPrima updateMp(long idMP, long idUnidad, BigDecimal costo,
			long idClasificacion) throws Exception {

		Unidad unidad = this.unidadDAO.getUnidadById(Long.valueOf(idUnidad)
				.intValue());

		Clasificacion clasificacion = this.clasificacionDAO
				.getClasificacionById(Long.valueOf(idClasificacion).intValue());


		MateriaPrima mp = materiaPrimaDao.updateMateriaPrima(idMP,unidad, costo, clasificacion);

		mp = materiaPrimaDao.getMateriaPrimaById(mp.getId());
		return mp;
	}

	
	public ComponenteValor getComponenteFromComposicion(MateriaPrima mp,
			Componente componente) {
		ComponenteValor cv = null;

		
//		ComponenteValor resultado = materiaPrimaDao.getComponenteFromComposicion(mp, componente);
		
		boolean noEncontrado = false;
		List<ComponenteValor> listadoCV = mp.getComposicion();
		for (int j = 0; j < listadoCV.size() && !noEncontrado; j++) {
			cv = (ComponenteValor) listadoCV.get(j);
			if ((cv).getComponente().equals(componente)) {
				noEncontrado = true;
				return cv;
			}
		}

//		if(resultado != null)
//			return resultado;
//		else{
			// si la mp no aporta cantiadad de este componente, es decir que no esta
			// en su composicion
			// se devuelve un componente de cantidad 0.
			ComponenteValor cv1 = new ComponenteValor();
			cv1.setComponente(componente);
			cv1.setCantidad(BigDecimal.ZERO);
			return cv1;
//		}

	}

	/**
	 * @return
	 */
	
	public int getCalculoColumnas(ArrayList<MateriaPrima> lista) {

		int cant = 0;
		Iterator mps = lista.iterator();
		int cantmp = 0;
		int cantComp = 0;
		while (mps.hasNext()) {
			MateriaPrima m = (MateriaPrima) mps.next();
			cantmp++;
			cantComp += m.getComposicion().size();
		}

		return cantComp;
	}


	
	public String getCostoXUnidadString(MateriaPrima materiaPrima) {
		Unidad unidadId = materiaPrima.getUnidad();
		if (unidadId != null && materiaPrima.getCosto().compareTo(BigDecimal.ZERO) >= 0) {
			return StringUtils.getSimela2decimales(materiaPrima
					.getCosto().toString()) + " " +
			// GestorPresentacion.getInstance().getValor("frame.gestionrestricciones.pesos")+
					"$/" + unidadId.getDescripcion();
		} else
			return "";
	}

	public ClasificacionDAO getClasificacionDAO() {
		return clasificacionDAO;
	}

	public void setClasificacionDAO(ClasificacionDAO clasificacionDAO) {
		this.clasificacionDAO = clasificacionDAO;
	}

	public GrupoDAO getGrupoDAO() {
		return grupoDAO;
	}

	public void setGrupoDAO(GrupoDAO grupoDAO) {
		this.grupoDAO = grupoDAO;
	}

	public void setUnidadDAO(UnidadDAO unidadDAO) {
		this.unidadDAO = unidadDAO;
	}

	public UnidadDAO getUnidadDAO() {
		return unidadDAO;
	}

	
//	public byte[] imprimirMp(UsuarioDTO usuario, String mpaimprimir,
//			HashMap hash, URI urlJasper) throws Exception {
//		try {
//
//			long idMp = Long.valueOf((String) mpaimprimir);
//			MateriaPrima mp = null;
//			try {
//				mp = materiaPrimaDao.getMateriaPrimaById(idMp);
//			} catch (Exception e) {
//				// TODO Auto-generated catch block
//				logger.error("",e);
//			}
//
//			return Reportes.reporteMP(mp, usuario, hash, urlJasper);
//
//		} catch (ExceptionAplicacion e) {
//			logger.error("",e);
//
//			mensaje = "No se puedo imprimir la planilla de formula. ";
//			throw new ExceptionAplicacion(mensaje,
//					ConstantesDTO.TipoException.INFORMACION);
//
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			logger.error("",e);
//		}
//		return null;
//	}
//
//	
//	public byte[] imprimirLitadoMp(UsuarioDTO usuario, HashMap hash,
//			URI urlJasper) throws Exception {
//		try {
//
//			return Reportes.reporteListaMP(usuario, hash, urlJasper);
//
//		} catch (ExceptionAplicacion e) {
//			logger.error("",e);
//
//			mensaje = "No se puedo imprimir la planilla de formula. ";
//			throw new ExceptionAplicacion(mensaje,
//					ConstantesDTO.TipoException.INFORMACION);
//
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			logger.error("",e);
//		}
//		return null;
//	}
//
//	
//	public byte[] imprimirLitadoMpCompleto(UsuarioDTO usuario, HashMap hash,
//			URI urlJasper) throws Exception {		
//		try {
//
//			return Reportes.reporte_todas_MP(usuario, hash, urlJasper);
//
//		} catch (ExceptionAplicacion e) {
//			logger.error("",e);
//
//			mensaje = "No se puedo imprimir la planilla de formula. ";
//			throw new ExceptionAplicacion(mensaje,
//					ConstantesDTO.TipoException.INFORMACION);
//
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			logger.error("",e);
//		}
//		return null;
//	}

	@Transactional
	
	public ComponenteValor updateCV(Integer idComponente, BigDecimal cantidad,
			MateriaPrima mp) throws Exception {
	    ComponenteValor cv = materiaPrimaDao.getComponenteFromComposicion(mp, idComponente);
		return componenteValorDao.updateCV(cv ,cantidad, mp, idComponente);
	}

	
	public MateriaPrima getMateriaPrimaByNombre(String nombre) throws Exception {
		return materiaPrimaDao.getMateriaPrimaByNombre(nombre);

	}

	
	public MateriaPrima getMpByNombreYGrupo(String nombre, long grupo)
			throws Exception {
		return materiaPrimaDao.getMateriaPrimaByNombreYGrupo(nombre, grupo);
	}


	public String toStringCodDescrip(MateriaPrima materiaPrima) {
		return materiaPrima.getId() + " - " + materiaPrima.getDescripcion();
	}

	public Object getCostoXUnidadString(MateriaPrima mp, BigDecimal costoMPaportada) {
		// TODO Auto-generated method stub
		return null;
	}


}